
module spi_apb_demux(
    // APB interface
    input                               m_pclk_i,
    input                               m_prstn_i,
    input  [31:0]                       m_paddr_i,
    input                               m_penable_i,
    input                               m_psel_i,
    input  [2 :0]                       m_pprot_i,
    input  [31:0]                       m_pwdata_i,
    input                               m_pwrite_i,
    output [31:0]                       m_prdata_o,

    // tx_bur APB interface
    output                              s0_pclk_o,
    output                              s0_prstn_o,
    output  [31:0]                      s0_paddr_o,
    output                              s0_penable_o,
    output                              s0_psel_o,
    output  [2 :0]                      s0_pprot_o,
    output  [31:0]                      s0_pwdata_o,
    output                              s0_pwrite_o,
    input   [31:0]                      s0_prdata_i,

    // rx_bur APB interface
    output                              s1_pclk_o,
    output                              s1_prstn_o,
    output  [31:0]                      s1_paddr_o,
    output                              s1_penable_o,
    output                              s1_psel_o,
    output  [2 :0]                      s1_pprot_o,
    output  [31:0]                      s1_pwdata_o,
    output                              s1_pwrite_o,
    input   [31:0]                      s1_prdata_i,

    // ctrl_regs APB interface
    output                              s2_pclk_o,
    output                              s2_prstn_o,
    output  [31:0]                      s2_paddr_o,
    output                              s2_penable_o,
    output                              s2_psel_o,
    output  [2 :0]                      s2_pprot_o,
    output  [31:0]                      s2_pwdata_o,
    output                              s2_pwrite_o,
    input   [31:0]                      s2_prdata_i
);
// 地址空间划分
localparam      RX_BUF_ADDR_START       = 16'h4000,   RX_BUF_ADDR_END    = 16'h4FFF;
localparam      TX_BUF_ADDR_START       = 16'h5000,   TX_BUF_ADDR_END    = 16'h5FFF;
localparam      CTRL_REGS_ADDR_START    = 16'h6000,   CTRL_REGS_ADDR_END = 16'h6FFF;


assign s0_psel_o = ((m_psel_i == 1'b1) && (RX_BUF_ADDR_START    <= m_paddr_i[15:0])    && (m_paddr_i[15:0] <= RX_BUF_ADDR_END))    ? 1'b1 : 1'b0;
assign s1_psel_o = ((m_psel_i == 1'b1) && (TX_BUF_ADDR_START    <= m_paddr_i[15:0])    && (m_paddr_i[15:0] <= TX_BUF_ADDR_END))    ? 1'b1 : 1'b0;
assign s2_psel_o = ((m_psel_i == 1'b1) && (CTRL_REGS_ADDR_START <= m_paddr_i[15:0])    && (m_paddr_i[15:0] <= CTRL_REGS_ADDR_END)) ? 1'b1 : 1'b0;

assign m_prdata_o       = ({32{s0_psel_o}} & s0_prdata_i) | 
                          ({32{s1_psel_o}} & s1_prdata_i) | 
                          ({32{s2_psel_o}} & s2_prdata_i) ;

assign s0_pclk_o        = m_pclk_i;
assign s0_prstn_o       = m_prstn_i;
assign s0_paddr_o       = m_paddr_i;
assign s0_penable_o     = m_penable_i;
assign s0_pprot_o       = m_pprot_i;
assign s0_pwdata_o      = m_pwdata_i;
assign s0_pwrite_o      = m_pwrite_i;

assign s1_pclk_o        = m_pclk_i;
assign s1_prstn_o       = m_prstn_i;
assign s1_paddr_o       = m_paddr_i;
assign s1_penable_o     = m_penable_i;
assign s1_pprot_o       = m_pprot_i;
assign s1_pwdata_o      = m_pwdata_i;
assign s1_pwrite_o      = m_pwrite_i;

assign s2_pclk_o        = m_pclk_i;
assign s2_prstn_o       = m_prstn_i;
assign s2_paddr_o       = m_paddr_i;
assign s2_penable_o     = m_penable_i;
assign s2_pprot_o       = m_pprot_i;
assign s2_pwdata_o      = m_pwdata_i;
assign s2_pwrite_o      = m_pwrite_i;

endmodule